package br.unifor.cct.mia.dataenhancement;

import java.awt.Point;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import br.unifor.cct.mia.util.Methods;

public class Database {
	
	private String dbFile;
	private List list = new ArrayList();
	
	public void add(String[] values) {
		list.add(values);
	}
	
	public void mountStr(Tuple tuple, List positions) {
        StringBuffer result = new StringBuffer();
        String[] values;
       
        int k = 0;
        for (Iterator it = list.iterator(); it.hasNext(); k++) {
           
            values = (String[])it.next();
            String valor = Arrays.toString(values).replaceAll("\\?", "X").trim();
            result.append( valor.substring(1, valor.length()-1) );
      
            /*for (int i = 0; i < values.length; i++) {
                if (positions.contains(new Point(k, i))) {
                	result.append("X");
                }
                else
                	result.append(values[i]);
               
                if (i + 1 < values.length) result.append(',');
            }*/
            result.append('\n');
        }

        tuple.addValue(result.toString());
    }
	
	public String toString() {
		String result = "";
		String[] values;
		
		for (Iterator it = list.iterator(); it.hasNext();) {
			values = (String[])it.next();
			for (int i = 0; i < values.length; i++) {
				if (i + 1 < values.length)
					result += values[i] + ',';
				else
					result += values[i];
			}
			result += '\n';
		}
				
		return result;
	}
	
	public String getLine(int pos) {
		String result = "";
		String[] line = (String[])list.get(pos);
		for (int i = 0; i < line.length; i++) {
			if (i + 1 < line.length)
				result += line[i] + ',';
			else
				result += line[i] + '\n';
		}
		return result;
	}

	public String[] getValues(int pos) {
		return (String[])list.get(pos);
	}
	
	public String getElement(int pos, int posCollumn) {
		return ((String[])list.get(pos))[posCollumn];
	}
	
	public int size() {
		return list.size();
	}
	
	public Object clone() {
		Database db = new Database();
		db.setDbFile(dbFile);
		for (int i = 0; i < list.size(); i++)
			db.list.add(((String[])list.get(i)).clone());
		
		return db;
	}
	public void updateValues(List positions, Structure st) {
		Point pt;
		String str = "";
		for (int i = 0; i < positions.size(); i++) {
			pt = (Point)positions.get( i );
			str = max(pt, st);
			if (!str.startsWith("-1")) ((String[])list.get(pt.x))[pt.y] = str;
			else {
				String[] a = str.split(" ");
				((String[])list.get(pt.x))[pt.y] = Integer.toString(Methods.randIntValue((int)Double.parseDouble(a[1]), (int)Double.parseDouble(a[2]))); 
			}
		}
	}
	
	public void updateValues(List positions, String[] values) {
		Point pt;
		for (int i = 0; i < positions.size(); i++) {
			pt = (Point)positions.get(i);
			((String[])list.get(pt.x))[pt.y] = values[i];
		}
	}

	/*public void updateValues(List positions) {
		Point pt;
		for (int i = 0; i < positions.size(); i++) {
			pt = (Point)positions.get(i);
			((String[])list.get(pt.x))[pt.y] = "?";
		}
	}
	*/
	
	public boolean equalsCondition(String[] t1, String[] t2) {
		if (t1.length != t2.length) return false;
		
		for (int i = 0; i < t1.length-1; i++) {
			if (!t1[i].equalsIgnoreCase(t2[i]))
				return false;
		}
		
		return true;
	}
	
	public boolean equalsPrediction(String[] t1, String[] t2) {
		return ( t1[t1.length-1].equalsIgnoreCase(t2[t2.length-1]) );
	}	
	
	public boolean equalsTuple(String[] t1, String[] t2) {	
		return ( equalsCondition(t1, t2) && equalsPrediction(t1, t2) );
	}
	
	public int[] conditionAndPrediction(Point pt) {
		int[] count = new int[3];
		String[] tuple = (String[])list.get(pt.x); 
		boolean cond = false, pre = false;
		
		for (int i = 0; i < list.size(); i++) {
			cond = equalsCondition((String[])list.get(i), tuple);
			pre = equalsPrediction((String[])list.get(i), tuple);
			if (cond && pre) {
				count[0] += 1;
				count[1] += 1;
				count[2] += 1;
			}
			else {
				if (cond) count[1] += 1;
				else if (pre) count[2] += 1;
			}
		}
		
		return count;
	}
	
	public String max(Point pt, Structure st) {
		int index = 0;
		if (st.getAttribute(pt.y).getTipo().equals(Attribute.DISCRETE)) {
			List lst = st.getValues(pt.y);
			int[] array = new int[lst.size()];
					
			for (int i = 0; i < list.size(); i++) {
				index = lst.indexOf(((String[])list.get(i))[pt.y]);
				if (index > -1) array[index] = array[index] + 1;
			}
			
			index = 0;
			int value = 0;
			for (int i = 0; i < array.length; i++) {
				value = array[i];
				if (array[index] < value) index = i;
			}
			return st.getValues(pt.y).get(index).toString();

		}
		else {
			return "-1 "+st.getAttribute(pt.y).getMin()+" "+st.getAttribute(pt.y).getMax();
		}
	}

	public String getDbFile() {
		return dbFile;
	}

	public void setDbFile(String dbFile) {
		this.dbFile = dbFile;
	}
	
	
}